/* Copyright 2001,2002,2003 NAH6 BV
 * All Rights Reserved
 *
 *  $Header: /var/lib/cvs/secphone/ui/KeyExchange/dhCalcNewPublicKeyRequest.cpp,v 1.6 2003/11/21 12:39:24 itsme Exp $
 *
 *
 * this generates a new diffiehellman private/public value pair.
 *
 */

#include "CPhone.h"

#include "dhCalcNewPublicKeyRequest.h"

#include "fnaPRNG.h"

bool CalcNewPublicKeyRequest::doCalculation()
{
    debug("DH: generating new public key\n");

    for (int i=0 ; i<2 ; i++)
    {
        if (!GenerateSecret(m_secret))
            return false;

        m_public= m_subgroup_generator.ModularPower(m_secret, m_modulus_prime);

        // make sure we don't send something accidentally from the
        // wrong subgroup.
        //
        // note that with the current parameter set the upper limit is never
        // reached, since m_modulus_prime is 4095 bits, and our public value
        // only 256 bits.
        //
        if (m_public>1 && m_public<m_modulus_prime-1)
            return true;
    }
    return false;
}


bool CalcNewPublicKeyRequest::GenerateSecret(Number& secret)
{
    int i;

    // attempt to generate random 10 times, before giving up.
    //
    // Note that at program startup this will indeed fail a couple of
    // times, until the random number generator is initialized properly.
    //
    for (i=0 ; i<10 ; i++)
    {
        ByteVector random;
        if (!theApp.m_rng->RandomData(32, random))
        {
            debug("DH-ERROR: error getting random data\n");
            // after the rng has failed, wait, so entropy may be gathered.
            Sleep(1000);
            return false;
        }
        m_secret.FromByteVector(random);

        // test if  1 < secret < q-1
        //  note that q is much larger than 256 bits,
        //  so the '<q-1' test will allways succeed.
        Number s2(m_secret+2);
        if (s2>=4 && s2<=m_subgroup_prime)
            break;
        debug("DH trying other secret\n");
    }
    if (i==10)
    {
        debug("DH-ERROR: could not generate proper secret - RNG not yet initialized? - check random generator\n");
        Sleep(1000);
        return false;
    }

    return true;
}

